home *** CD-ROM | disk | FTP | other *** search
/ Personal Paint v7.1 / Cloanto Personal Paint v7.1.iso / rexx / saveanimgif.pprx < prev    next >
Text File  |  1997-05-06  |  18KB  |  632 lines

  1. /* Personal Paint Amiga Rexx script - Copyright ⌐ 1996, 1997 Cloanto Italia srl */
  2.  
  3. /* $VER: SaveAnimGif.pprx 1.6 */
  4.  
  5. /** ENG
  6.  This script saves the current anim-brush as a GIF animation file. Specific
  7.  features of the GIF animation specification can be set through a requester.
  8.  
  9.  This script checks for the differences between frames and only stores
  10.  the smallest rectangular region containing changes. Other techniques
  11.  are employed for additional compression. The resulting GIF animations are
  12.  highly optimized and occupy considerably less space than GIF animations
  13.  created with other tools available on the Amiga.
  14.  
  15.  The "Use Loop" option inserts an "Application Extension Block" into the GIF
  16.  file (as implemented by Netscape in its Navigator software from version 2).
  17.  This additional block, which is interpreted by most other browsers
  18.  supporting GIF animations, specifies that the animation be repeated as many
  19.  times as indicated by the "Loop" value. A value of 0 expressly means
  20.  "loop continuously".
  21.  
  22.  The list of frames shows the timing value for each frame, in seconds/100.
  23.  These values can be selected, edited and applied to one or more frames.
  24.  Alternatively, the timing can be copied automatically from the current
  25.  animation. If this option is selected ("From Animation"), then the
  26.  "Delay" value is used to indicate from which animation frame the timing
  27.  values are to be copied.
  28.  
  29.  The "Transparency" setting indicates the current transparency status of
  30.  the anim-brush. If transparency is not required by the animation, it is
  31.  recommended to leave this option disabled.
  32.  
  33.  Note: an "anim-brush" is a part of a full-screen animation. It can be
  34.  either loaded or defined manually after clicking three times on the
  35.  Define Brush tool.
  36. */
  37.  
  38. /** DEU
  39.  Dieses Skript dient zum Speichern des aktuellen Anim-Brushes als
  40.  GIF-Animation. Eine Reihe spezifischer Merkmale des Animationsformats lΣ▀t
  41.  sich in einem dazugeh÷rigen Dialogfenster auswΣhlen.
  42.  
  43.  Nach der Skriptausfⁿhrung werden zwei aufeinanderfolgende Frames zunΣchst
  44.  auf Unterschiede untersucht. Gespeichert wird dann nur der kleinste
  45.  rechteckige Bereich, der Unterschiede zwischen den beiden Bildern aufweist.
  46.  Au▀erdem werden zum Erzielen einer weiter verbesserten Komprimierung noch
  47.  andere Verfahren angewendet. Die daraus resultierenden hochoptimierten
  48.  GIF-Animationen ben÷tigen erheblich weniger Speicherplatz als solche, die
  49.  mit anderen fⁿr den Amiga erhΣltlichen Tools erstellt worden sind.
  50.  
  51.  Durch die Option "Schleife aktiv:" wird der GIF-Datei eine
  52.  Programmerweiterung ("Application Extension Block") hinzugefⁿgt, wie sie von
  53.  Netscape im Navigator ab Version 2 implementiert ist. Dieser auch von den
  54.  meisten anderen Browsern, die GIF-Animationen unterstⁿtzen, interpretierte
  55.  Block legt fest, da▀ die Animation so oft wiederholt wird, wie unter
  56.  "Schleife:" angegeben. Ein Wert von 0 bewirkt das Abspielen in einer
  57.  Endlosschleife.
  58.  
  59.  Die Frameliste zeigt den Timingwert fⁿr jedes Einzelbild in Hundertstel
  60.  Sekunden. Diese Werte lassen sich auswΣhlen, bearbeiten und anschlie▀end
  61.  einem oder mehreren Einzelbildern zuweisen. Alternativ dazu k÷nnen die
  62.  Timingwerte automatisch aus der aktuellen Animation kopiert werden. Wenn die
  63.  entsprechende Option aktiviert ist ("Von Animation"), wird der
  64.  "Verz÷gerung"-Wert verwendet, um anzuzeigen, von welchem Einzelbild der
  65.  Animation die Timingwerte kopiert werden sollen.
  66.  
  67.  Die "Transparenz"-Einstellung gibt den aktuellen Transparenzstatus des
  68.  Animationspinsels wieder. Erfordert die Animation keine Transparenz, so wird
  69.  empfohlen, diese Option ausgeschaltet zu lassen.
  70.  
  71.  Hinweis: Ein Animationspinsel ist ein Bestandteil einer normalen Animation.
  72.  Er lΣ▀t sich nach einem Dreifachklick auf das Pinseldefinitionswerkzeug
  73.  entweder laden oder manuell definieren.
  74. */
  75.  
  76. /** ITA
  77.  Questo script salva l'anim-brush corrente come un'animazione GIF. Si possono
  78.  impostare le caratteristiche peculiari di una animazione GIF tramite una
  79.  apposita finestra di dialogo.
  80.  
  81.  Questo script controlla eventuali differenze tra fotogrammi e salva solo
  82.  la pi∙ piccola regione rettangolare che contiene modifiche. Altre tecniche
  83.  sono utilizzate per una compressione aggiuntiva. Le animazioni GIF risultanti
  84.  sono altamente ottimizzate ed occupano molto meno spazio di quelle create con
  85.  altri programmi disponibili su Amiga.
  86.  
  87.  L'opzione "Usare ciclo" inserisce un "Application Extension Block" nel file GIF
  88.  (come implementato da Netscape nel suo programma Navigator a partire dalla
  89.  versione 2). Questo blocco aggiuntivo, che viene interpretato dalla maggior
  90.  parte degli altri programmi di navigazione che permettono l'uso di animazioni
  91.  GIF, specifica che l'animazione deve essere ripetuta tante volte quante
  92.  indicato dal valore "Ciclo". Un valore pari a 0 significa espressamente
  93.  "ciclo continuo".
  94.  
  95.  L'elenco dei fotogrammi mostra il valore di temporizzazione per ciascun
  96.  fotogramma, in centesimi di secondo. Tali valori possono essere selezionati,
  97.  modificati e applicati a uno o pi∙ fotogrammi. In alternativa, la
  98.  temporizzazione pu≥ essere copiata automaticamente dall'animazione corrente.
  99.  Se questa opzione Φ attiva ("Da animazione"), si usa il valore di
  100.  "Temporizzazione fotogrammi" per indicare da quale fotogramma dell'animazione
  101.  si devono copiare i valori di temporizzazione.
  102.  
  103.  L'impostazione di "Trasparenza" indica lo stato attuale della trasparenza
  104.  dell'anim-brush. Se l'animazione non richiede la trasparenza, Φ consigliabile
  105.  lasciare disattivata questa opzione.
  106.  
  107.  Nota: un "anim-brush" Φ un pennello, e come tale in genere una (pi∙ piccola)
  108.  parte di un'animazione a tutto schermo. Un anim-brush pu≥ essere caricare,
  109.  oppure definito manualmente facendo click tre volte sullo strumento
  110.  Definire pennello.
  111. */
  112.  
  113. IF ARG(1, EXISTS) THEN
  114.     PARSE ARG PPPORT
  115. ELSE
  116.     PPPORT = 'PPAINT'
  117.  
  118. IF ~SHOW('P', PPPORT) THEN DO
  119.     IF EXISTS('PPaint:PPaint') THEN DO
  120.         ADDRESS COMMAND 'Run >NIL: PPaint:PPaint'
  121.         DO 30 WHILE ~SHOW('P',PPPORT)
  122.              ADDRESS COMMAND 'Wait >NIL: 1 SEC'
  123.         END
  124.     END
  125.     ELSE DO
  126.         SAY "Personal Paint could not be loaded."
  127.         EXIT 10
  128.     END
  129. END
  130.  
  131. IF ~SHOW('P', PPPORT) THEN DO
  132.     SAY 'Personal Paint Rexx port could not be opened'
  133.     EXIT 10
  134. END
  135.  
  136. ADDRESS VALUE PPPORT
  137. OPTIONS RESULTS
  138. OPTIONS FAILAT 10000
  139.  
  140. Get 'LANG'
  141. IF RESULT = 1 THEN DO        /* Deutsch */
  142.     txt_title_req     = 'GIF-Anim-Brush speichern'
  143.     txt_title_set     = 'GIF-Anim-Brush-Einstellungen'
  144.     txt_title_delay   = 'Frame-Verz÷gerung'
  145.     txt_gad_delay     = 'Frame-Verz÷gerungen:'
  146.     txt_gad_annot     = '_Bemerkung:'
  147.     txt_gad_loop      = '_Schleife:'
  148.     txt_gad_useloop   = 'Schleife ak_tiv:'
  149.     txt_gad_transp    = '_Transparenz:'
  150.     txt_gad_del       = '_Verz÷gerung:'
  151.     txt_gad_deltype   = ' '
  152.     txt_gad_deltype0  = '1/100\""'
  153.     txt_gad_deltype1  = 'Von Animation'
  154.     txt_gad_from      = 'A_b Frame:'
  155.     txt_gad_to        = 'Bi_s Frame:'
  156.     txt_err_oldclient = 'Fⁿr dieses Skript_ist eine neuere Version_von Personal Paint erforderlich'
  157.     txt_err_oldlib    = 'Fⁿr dieses Skript ist eine neuere Version_der GIF library erforderlich'
  158.     txt_err_notabsh   = 'Aktueller Brush_ist kein Anim-Brush'
  159.     txt_err_notemp    = 'Zu wenig Speicher_fⁿr temporΣren Brush'
  160.     txt_err_nomem     = 'Speichermangel'
  161.     txt_err_nosave    = 'Fehler bei Datei-Ein-/Ausgabe'
  162. END
  163. ELSE IF RESULT = 2 THEN DO    /* Italiano */
  164.     txt_title_req     = 'Scrivere Anim-brush GIF'
  165.     txt_title_set     = 'Parametri Anim-brush GIF'
  166.     txt_title_delay   = 'Temporizzazione'
  167.     txt_gad_delay     = 'Temporizzazione fotogrammi:'
  168.     txt_gad_annot     = '_Note:'
  169.     txt_gad_loop      = 'Cic_lo:'
  170.     txt_gad_useloop   = '_Usare ciclo:'
  171.     txt_gad_transp    = '_Transparenza:'
  172.     txt_gad_del       = '_Temporizzazione:'
  173.     txt_gad_deltype   = ' '
  174.     txt_gad_deltype0  = '1/100\""'
  175.     txt_gad_deltype1  = 'Da animazione'
  176.     txt_gad_from      = 'Da _fotogramma:'
  177.     txt_gad_to        = 'A f_otogramma:'
  178.     txt_err_oldclient = 'Questa procedura richiede_una versione pi∙ recente_di Personal Paint'
  179.     txt_err_oldlib    = 'Questa procedura richiede_una versione pi∙ recente_della libreria GIF'
  180.     txt_err_notabsh   = 'Il pennello attuale_non Φ un anim-brush'
  181.     txt_err_notemp    = 'Impossibile creare_pennello temporaneo'
  182.     txt_err_nomem     = 'Memoria insufficiente'
  183.     txt_err_nosave    = 'Errore di scrittura'
  184. END
  185. ELSE DO                /* English */
  186.     txt_title_req     = 'Save GIF Anim-Brush'
  187.     txt_title_set     = 'GIF Anim-Brush Settings'
  188.     txt_title_delay   = 'Frame Delay'
  189.     txt_gad_delay     = 'Frame Delays:'
  190.     txt_gad_annot     = '_Annotation:'
  191.     txt_gad_loop      = '_Loop:'
  192.     txt_gad_useloop   = '_Use Loop:'
  193.     txt_gad_transp    = '_Transparency:'
  194.     txt_gad_del       = '_Delay:'
  195.     txt_gad_deltype   = ' '
  196.     txt_gad_deltype0  = '1/100\""'
  197.     txt_gad_deltype1  = 'From Animation'
  198.     txt_gad_from      = '_From Frame:'
  199.     txt_gad_to        = 'T_o Frame:'
  200.     txt_err_oldclient = 'This script requires a newer_version of Personal Paint'
  201.     txt_err_oldlib    = 'This script requires a newer_version of the GIF library'
  202.     txt_err_notabsh   = 'The current brush_is not an anim-brush'
  203.     txt_err_notemp    = 'No space for temporary brush'
  204.     txt_err_nomem     = 'Not enough memory'
  205.     txt_err_nosave    = 'File I/O error'
  206. END
  207.  
  208. Version 'REXX'
  209. IF RESULT < 7 THEN DO
  210.     RequestNotify 'PROMPT "'txt_err_oldclient'"'
  211.     EXIT 10
  212. END
  213.  
  214. LockGUI
  215. GetBrushAttributes 'FRAMES'
  216. frames = RESULT
  217.  
  218. IF frames < 2 THEN DO
  219.     RequestNotify 'PROMPT "'txt_err_notabsh'"'
  220.     UnlockGUI
  221.     EXIT 0
  222. END
  223.  
  224. GetBrushNumber
  225. bshnum = RESULT
  226.  
  227. SetCurrentBrush 'UNUSED'
  228. IF RC ~= 0 THEN DO
  229.     RequestNotify 'PROMPT "'txt_err_notemp'"'
  230.     UnlockGUI
  231.     EXIT 0
  232. END
  233. GetBrushNumber
  234. tbshnum = RESULT
  235.  
  236. SetCurrentBrush 'BRUSH' bshnum
  237. GetBrushInfo 'ANNOTATION'
  238. frame_annot = RESULT
  239.  
  240. loop = -1
  241. delay. = 0
  242. IF WORD(frame_annot, 1) = 'LOOP' & WORD(frame_annot, 3) = 'DELAY' THEN DO
  243.     loop = WORD(frame_annot, 2)
  244.     IF ~DATATYPE(loop, 'W') THEN
  245.         loop = -1
  246.     DO frm = 1 TO frames
  247.         del = WORD(frame_annot, 3+frm)
  248.         IF DATATYPE(del, 'W') THEN
  249.             delay.frm = del
  250.     END
  251. END
  252. use_loop = (loop >= 0)
  253. IF loop < 0 THEN
  254.     loop = 0
  255.  
  256. fnlen = LENGTH(frames)
  257. dsel = 1
  258. do_req = 1
  259. deltype = 0
  260.  
  261. GetBrushInfo 'COPYRIGHT'
  262. annot = RESULT
  263. max_annot_size = LENGTH(annot) * 2
  264. IF max_annot_size < 200 THEN
  265.     max_annot_size = 200
  266.  
  267. GetBrushAttributes 'TRANSPARENCY'
  268. transp = RESULT
  269. IF transp ~= 1 THEN
  270.     transp = 0
  271.  
  272. DO WHILE do_req
  273.     ppos = 1
  274.     DO FOREVER
  275.         ppos = INDEX(annot, '"', ppos)
  276.         IF ppos = 0 THEN BREAK
  277.         annot = INSERT('\"', annot, ppos-1)
  278.         ppos = ppos + 3
  279.     END
  280.  
  281.     req = '"LIST ACTION = ""'txt_gad_delay'"", 'frames', 'dsel-1', 20, 7'
  282.     DO frm = 1 TO frames
  283.         req = req || ', ""'RIGHT(frm, fnlen) || ':' delay.frm || '""'
  284.     END
  285.  
  286.     req = req ||,
  287.       ' STRING = ""'txt_gad_annot'"", 'max_annot_size', ""'annot'"" ' ||,
  288.         ' INTSTR = ""'txt_gad_loop'"", 0, 32767, 'loop' ' ||,
  289.         ' CHECK = ""'txt_gad_useloop'"", 'use_loop' ' ||,
  290.         ' CHECK = ""'txt_gad_transp'"", 'transp' "'
  291.  
  292.     Request 'RESIZE "'txt_title_set'"' req
  293.     IF RC = 0 THEN DO
  294.         dsel  = RESULT.1 + 1
  295.         annot = RESULT.2
  296.         loop  = RESULT.3
  297.         use_loop = RESULT.4
  298.         transp = RESULT.5
  299.  
  300.         IF RESULT = -1 THEN DO
  301.             Request '"'txt_title_delay'" ' ||,
  302.                         '"INTSTR = ""'txt_gad_del'"", 0, 32767, 'delay.dsel' ' ||,
  303.                         ' CYCLE = ""'txt_gad_deltype'"", 2, 'deltype', ""'txt_gad_deltype0'"", ""'txt_gad_deltype1'"" ' ||,
  304.                         ' SEPARATOR ' ||,
  305.                         ' INTSTR = ""'txt_gad_from'"", 1, 'frames', 'dsel' ' ||,
  306.                         ' INTSTR = ""'txt_gad_to'"", 1, 'frames', 'dsel' "'
  307.             IF RC = 0 THEN DO
  308.                 del     = RESULT.1
  309.                 deltype = RESULT.2
  310.                 frfrom  = RESULT.3
  311.                 frto    = RESULT.4
  312.                 frstep  = SIGN(frto - frfrom)
  313.                 IF frstep = 0 THEN
  314.                     frstep = 1
  315.                 DO frm = frfrom TO frto BY frstep
  316.                     IF deltype THEN DO
  317.                         IF del < 1 THEN
  318.                             del = 1
  319.                         GetFrameDelay 'FRAME' del
  320.                         IF RC = 0 THEN
  321.                             delay.frm = TRUNC((RESULT * 100 / 60) + 0.5)
  322.                         del = del + frstep
  323.                     END
  324.                     ELSE delay.frm = del
  325.                 END
  326.             END
  327.         END
  328.         ELSE do_req = 0
  329.     END
  330.     ELSE DO
  331.         UnlockGUI
  332.         EXIT 0
  333.     END
  334. END
  335.  
  336. IF ~use_loop THEN
  337.     loop = -1
  338. frame_annot = 'LOOP' loop 'DELAY'
  339. DO frm = 1 TO frames
  340.     frame_annot = frame_annot delay.frm
  341. END
  342. SetBrushInfo 'ANNOTATION "'frame_annot'"'
  343.  
  344.  
  345. RequestFile '"'txt_title_req'" SAVEMODE'
  346. IF RC = 0 THEN DO
  347.     PARSE VALUE RESULT WITH '"' fname '"'
  348.     tempfile = 'T:PP_AnGif.'PRAGMA('ID')
  349.  
  350.     GetBrushAttributes 'FRAMEFIRST'
  351.     sv_frmin = RESULT
  352.     GetBrushAttributes 'FRAMELAST'
  353.     sv_frmax = RESULT
  354.     GetBrushAttributes 'LENGTH'
  355.     sv_frlen = RESULT
  356.     GetBrushAttributes 'FRAMEPOSITION'
  357.     sv_frpos = RESULT
  358.     Get 'ICONS'
  359.     sv_icons = RESULT
  360.  
  361.     GetBrushAttributes 'WIDTH'
  362.     bwidth = RESULT
  363.     GetBrushAttributes 'HEIGHT'
  364.     bheight = RESULT
  365.  
  366.     GetBrushAttributes 'TRANSPARENTCOLOR'
  367.     transpcol = RESULT
  368.     GetBrushAttributes 'COLORS'
  369.     bcolors = RESULT
  370.     plt_size = bcolors * 3
  371.  
  372.     Get 'PATHBSH'
  373.     PARSE VAR RESULT '"' sv_pathbsh '"'
  374.  
  375.     IF transp = 1 THEN
  376.         pckinfo = '09'x
  377.     ELSE
  378.         pckinfo = '00'x
  379.  
  380.     DO bdepth = 1 TO 8
  381.         IF bcolors = (2 ** bdepth) THEN
  382.             BREAK
  383.     END
  384.  
  385.     tbmap.0 = 0
  386.     tbmap.1 = 0
  387.     tbnum = 0
  388.     gfile_open = 0
  389.     last_plt = ''
  390.     err_msg = ''
  391.  
  392.     SIGNAL ON Break_C
  393.  
  394.     AllocateBitmap bwidth bheight bdepth
  395.     IF RC = 0 THEN DO
  396.         tbmap.0 = RESULT
  397.  
  398.         AllocateBitmap bwidth bheight bdepth
  399.         IF RC = 0 THEN DO
  400.             tbmap.1 = RESULT
  401.  
  402.             SetBrushAttributes 'FRAMEFIRST 1 FRAMELAST' frames 'LENGTH' frames
  403.             Set '"ICONS = 0"'
  404.  
  405.             DO frm = 1 TO frames
  406.                 SetCurrentBrush 'BRUSH' bshnum
  407.                 IF RC ~= 0 THEN DO
  408.                     err_msg = txt_err_nomem
  409.                     BREAK
  410.                 END
  411.  
  412.                 SetBrushAttributes 'FRAMEPOSITION' frm
  413.                 IF RC ~= 0 THEN DO
  414.                     err_msg = txt_err_nomem
  415.                     BREAK
  416.                 END
  417.  
  418.                 GetBitmap '0 0 BITMAP' tbmap.tbnum 'FROMBRUSH'
  419.                 tbnum = 1 - tbnum
  420.  
  421.                 IF frm = 1 THEN DO
  422.                     dx0 = 0
  423.                     dy0 = 0
  424.                     dx1 = bwidth - 1
  425.                     dy1 = bheight - 1
  426.                 END
  427.                 ELSE DO
  428.                     IF transp = 1 THEN
  429.                         GetBrushAttributes 'BOUNDARIES'
  430.                     ELSE
  431.                         GetBitmapDelta tbmap.0 tbmap.1
  432.  
  433.                     PARSE VAR RESULT dx0 dy0 dx1 dy1 .
  434.                     IF dx0 < 0 THEN DO
  435.                         dx0 = 0
  436.                         dy0 = 0
  437.                         dx1 = 0
  438.                         dy1 = 0
  439.                     END
  440.                 END
  441.  
  442.                 SetCurrentBrush 'BRUSH' tbshnum
  443.                 IF RC ~= 0 THEN DO
  444.                     err_msg = txt_err_nomem
  445.                     BREAK
  446.                 END
  447.  
  448.                 CopyBrush bshnum dx0 dy0 dx1 dy1 'NOFRAMES'
  449.                 IF RC ~= 0 THEN DO
  450.                     err_msg = txt_err_nomem
  451.                     BREAK
  452.                 END
  453.  
  454.                 SaveBrush tempfile 'FORCE QUIET NOPROGRESS FORMAT "GIF" OPTIONS "GIF89=1" "PROGDSP=0" "SCRFMT=0"'
  455.                 IF RC ~= 0 THEN DO
  456.                     IF RC = 46 | RC = 47 THEN
  457.                         err_msg = txt_err_oldlib
  458.                     ELSE
  459.                         err_msg = txt_err_nosave
  460.                     BREAK
  461.                 END
  462.  
  463.                 IF ~OPEN('tfile', tempfile, 'R') THEN DO
  464.                     err_msg = txt_err_nosave
  465.                     BREAK
  466.                 END
  467.  
  468.                 IF frm = 1 THEN DO
  469.                     IF ~OPEN('gfile', fname, 'W') THEN DO
  470.                         err_msg = txt_err_nosave
  471.                         BREAK
  472.                     END
  473.                     gfile_open = 1
  474.                     data = READCH('tfile', 13)        /* sign + screen descriptor */
  475.                     bxpix = BITOR(BITAND(SUBSTR(data, 11, 1), '07'x), '80'x)
  476.                     CALL WRITECH('gfile', data)
  477.  
  478.                     plt_data = READCH('tfile', plt_size)    /* palette */
  479.                     CALL WRITECH('gfile', plt_data)
  480.                     do_plt = 0
  481.  
  482.                     IF use_loop THEN
  483.                         CALL WRITECH('gfile', '21FF0B'x || 'NETSCAPE2.0' || '0301'x || IntelWord(loop) || '00'x)
  484.  
  485.                     IF annot ~= '' THEN DO        /* annotation */
  486.                         CALL WRITECH('gfile', '21FE'x)
  487.                         alen = LENGTH(annot)
  488.                         apos = 1
  489.                         DO WHILE alen > 0
  490.                             IF alen <= 255 THEN
  491.                                 aln = alen
  492.                             ELSE
  493.                                 aln = 255
  494.                             CALL WRITECH('gfile', D2C(aln) || SUBSTR(annot, apos, aln))
  495.                             apos = apos + aln
  496.                             alen = alen - aln
  497.                         END
  498.                         CALL WRITECH('gfile', '00'x)
  499.                     END
  500.                 END
  501.                 ELSE DO
  502.                     CALL SEEK('tfile', 13, 'B')
  503.                     plt_data = READCH('tfile', plt_size)
  504.                     do_plt = (plt_data ~== last_plt)
  505.                 END
  506.                 last_plt = plt_data
  507.  
  508.                 DO FOREVER
  509.                     code = READCH('tfile', 1)
  510.  
  511.                     IF code = ',' THEN DO    /* image */
  512.                         /* gfx control */
  513.                         CALL WRITECH('gfile', '21F904'x || pckinfo || IntelWord(delay.frm) || D2C(transpcol) || '00'x)
  514.  
  515.                         data = READCH('tfile', 9)        /* Get image descriptor */
  516.                         imginfo = SUBSTR(data, 9, 1)
  517.                         IF do_plt THEN
  518.                             imginfo = BITOR(BITAND(imginfo, '40'x), bxpix)
  519.  
  520.                         /* image descriptor */
  521.                         CALL WRITECH('gfile', ',' || IntelWord(dx0) || IntelWord(dy0) || IntelWord(dx1-dx0+1) || IntelWord(dy1-dy0+1) || imginfo)
  522.  
  523.                         IF do_plt THEN
  524.                             CALL WRITECH('gfile', plt_data)
  525.  
  526.                         tpos = SEEK('tfile', 0, 'C')
  527.                         epos = SEEK('tfile', 0, 'E')
  528.                         dsize = epos - tpos - 1
  529.                         CALL SEEK('tfile', tpos, 'B')
  530.  
  531.                         /* image data */
  532.                         DO WHILE dsize > 0
  533.                             IF dsize > 65000 THEN
  534.                                 tsize = 65000
  535.                             ELSE
  536.                                 tsize = dsize
  537.                             data = READCH('tfile', tsize)
  538.                             CALL WRITECH('gfile', data)
  539.                             dsize = dsize - tsize
  540.                         END
  541.                         BREAK
  542.                     END
  543.                     ELSE IF code = '!' THEN DO        /* extension */
  544.                         CALL SEEK('tfile', 1, 'C')
  545.                         length = 1
  546.                         DO WHILE length ~= 0
  547.                             length = C2D(READCH('tfile', 1))
  548.                             IF length > 0 THEN
  549.                                 CALL SEEK('tfile', length, 'C')
  550.                         END
  551.                     END
  552.                     ELSE BREAK
  553.                 END
  554.  
  555.                 CALL CLOSE('tfile')
  556.             END
  557.  
  558.             CALL WRITECH('gfile', ';')
  559.             CALL CLOSE('gfile')
  560.             gfile_open = 0
  561.  
  562.             ADDRESS COMMAND 'Delete >NIL: 'tempfile
  563.  
  564.             SetCurrentBrush 'BRUSH' tbshnum
  565.             IF RC = 0 THEN
  566.                 FreeBrush 'FORCE'
  567.  
  568.             SetCurrentBrush 'BRUSH' bshnum
  569.             IF RC = 0 THEN
  570.                 SetBrushAttributes 'FRAMEFIRST' sv_frmin 'FRAMELAST' sv_frmax 'LENGTH' sv_frlen 'FRAMEPOSITION' sv_frpos
  571.  
  572.             Set '"ICONS =' sv_icons '"'
  573.  
  574.             FreeBitmap tbmap.1
  575.         END
  576.         ELSE err_msg = txt_err_nomem
  577.  
  578.         FreeBitmap tbmap.0
  579.     END
  580.     ELSE err_msg = txt_err_nomem
  581.  
  582.     IF err_msg ~= '' THEN
  583.         RequestNotify 'PROMPT "'err_msg'"'
  584.  
  585.     Set '"PATHBSH=""'sv_pathbsh'"" "'
  586. END
  587. UnlockGUI
  588.  
  589. EXIT 0
  590.  
  591.  
  592.  
  593.  
  594. IntelWord: PROCEDURE
  595.  
  596.     value = ARG(1)
  597.  
  598.     hibyte = value % 256
  599.     lobyte = value - (hibyte * 256)
  600.  
  601.     RETURN D2C(lobyte) || D2C(hibyte)
  602.  
  603.  
  604.  
  605.  
  606. Break_C:
  607.  
  608.     IF gfile_open THEN
  609.         CALL CLOSE('gfile')
  610.  
  611.     ADDRESS COMMAND 'Delete >NIL: 'tempfile
  612.  
  613.     SetCurrentBrush 'BRUSH' tbshnum
  614.     IF RC = 0 THEN
  615.         FreeBrush 'FORCE'
  616.  
  617.     SetCurrentBrush 'BRUSH' bshnum
  618.     IF RC = 0 THEN
  619.         SetBrushAttributes 'FRAMEFIRST' sv_frmin 'FRAMELAST' sv_frmax 'LENGTH' sv_frlen 'FRAMEPOSITION' sv_frpos
  620.  
  621.     Set '"ICONS =' sv_icons '"'
  622.  
  623.     IF tbmap.1 ~= 0 THEN
  624.         FreeBitmap tbmap.1
  625.  
  626.     IF tbmap.0 ~= 0 THEN
  627.         FreeBitmap tbmap.0
  628.  
  629.     Set '"PATHBSH=""'sv_pathbsh'"" "'
  630.  
  631.     RETURN
  632.